home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
c
/
julin105.zip
/
JULIAN.C
< prev
Wrap
C/C++ Source or Header
|
1993-08-02
|
8KB
|
433 lines
/********************************************************************
* *
* JULIAN DATE LIBRARY (c)Copyright 1992 by CalcShop Inc. *
* All rights reserved. *
* *
* JULIAN v1.05 d08/02/93 *
* *
* *
* Robert Emmons *
* CalcShop Inc. *
* P.O Box 1231 *
* W. Caldwell, NJ 07007 *
* Phones: (201)228-9139 or (800)466-3469 *
* *
********************************************************************/
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <stdio.h> /* for sprintf() */
#include "juldef.h"
/*
**************************************************************************
These functions convert from Gregorian dates to Julian day numbers
**************************************************************************
*/
long gregtojday(GDATE gdate)
{
int prvyear, leaps;
long jday;
/*
gregtojday calculates the julian day number for a date, using
JAN 1 0001 AD as day number 1.
gregtojday works from JAN 1 0001 AD ad infinatum, ignoring the
unusual calendar modifications which were sometimes used
in the past.
*/
/* calc the number of leap years which preceeded the current year */
prvyear = gdate.year - 1;
leaps = prvyear / 4 - prvyear / 100 + prvyear / 400;
/* calc julian day number */
jday = gregtoyday(gdate); /* calc day of year */
if(jday > BADDATE)
jday += (long)prvyear * 365l + (long)leaps;
return(jday);
}
int gregtoyday(GDATE gdate)
{
int yday, leapyear;
/*
gregtoyday calculates the julian day for a date,
using JAN 1 of the current year as day number 1.
*/
leapyear = isleap(gdate.year); /* returns TRUE or FALSE */
/* check # days in month */
if(gdate.day <= 0)
return(BADDAY);
switch(gdate.month)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if(gdate.day > 31)
return(BADDAY);
break;
case 2:
if(gdate.day > 29)
return(BADDAY);
else if(leapyear == FALSE && gdate.day > 28)
return(BADDAY);
break;
case 4:
case 6:
case 9:
case 11:
if(gdate.day > 30)
return(BADDAY);
break;
default:
return(BADMONTH);
}
switch(gdate.month)
{
default:
yday = BADMONTH;
break;
case 1:
yday = gdate.day;
break;
case 2:
yday = gdate.day + 31;
break;
case 3:
yday = gdate.day + 59;
break;
case 4:
yday = gdate.day + 90;
break;
case 5:
yday = gdate.day + 120;
break;
case 6:
yday = gdate.day + 151;
break;
case 7:
yday = gdate.day + 181;
break;
case 8:
yday = gdate.day + 212;
break;
case 9:
yday = gdate.day + 243;
break;
case 10:
yday = gdate.day + 273;
break;
case 11:
yday = gdate.day + 304;
break;
case 12:
yday = gdate.day + 334;
break;
}
/* check year */
if(gdate.year < 0)
return(BADYEAR);
if(leapyear == TRUE && gdate.month != 1 && gdate.month != 2)
++yday;
return(yday);
}
double gregtojear(GDATE gdate)
{
return(gregtojday(gdate) / AVYRDAYS + 1.0);
}
/*
**************************************************************************
These functions convert from Julian day numbers to Gregorian dates
**************************************************************************
*/
GDATE jdaytogreg(long jday)
{
GDATE gdate;
/* calc year and yearday */
gdate = jdaytoyday(jday);
/* calc month and day */
gdate = ydaytogreg(gdate.day, gdate.year);
return(gdate);
}
GDATE jdaytoyday(long jday)
{
int quadcents, remcents, remquads, remyears;
GDATE gdate;
gdate.month = BADMONTH; /* dummy value */
quadcents = jday / QCENTDAYS;
jday -= QCENTDAYS * quadcents;
if(jday < 1){
gdate.year = 400 * quadcents;
gdate.day = YEARDAYS + 1;
return gdate;
}
remcents = jday / CENTDAYS;
jday -= CENTDAYS * remcents;
if(jday < 1){
gdate.year = 400 * quadcents + 100 * remcents;
gdate.day = YEARDAYS;
return gdate;
}
remquads = jday / QUADDAYS;
jday -= QUADDAYS * remquads;
if(jday < 1){
gdate.year = 400 * quadcents + 100 * remcents + 4 * remquads;
gdate.day = YEARDAYS + 1;
return gdate;
}
remyears = jday / YEARDAYS;
jday -= YEARDAYS * remyears;
if(jday < 1){
gdate.year = 400 * quadcents + 100 * remcents
+ 4 * remquads + remyears;
gdate.day = YEARDAYS;
return gdate;
}
gdate.year = 1 + 400 * quadcents + 100 * remcents
+ 4 * remquads + remyears;
gdate.day = jday;
return gdate;
}
GDATE ydaytogreg(int yday, int year)
{
int leap;
GDATE gdate;
gdate.year = year;
leap = isleap(gdate.year);
if(yday < 1)
{
gdate.month = 12;
gdate.day = 31;
}
else if(yday <= 31)
{
gdate.month = 1;
gdate.day = yday;
}
else if(yday <= leap + 59)
{
gdate.month = 2;
gdate.day = yday - 31;
}
else if(yday <= leap + 90)
{
gdate.month = 3;
gdate.day = yday - leap - 59;
}
else if(yday <= leap + 120)
{
gdate.month = 4;
gdate.day = yday - leap - 90;
}
else if(yday <= leap + 151)
{
gdate.month = 5;
gdate.day = yday - leap - 120;
}
else if(yday <= leap + 181)
{
gdate.month = 6;
gdate.day = yday - leap - 151;
}
else if(yday <= leap + 212)
{
gdate.month = 7;
gdate.day = yday - leap - 181;
}
else if(yday <= leap + 243)
{
gdate.month = 8;
gdate.day = yday - leap - 212;
}
else if(yday <= leap + 273)
{
gdate.month = 9;
gdate.day = yday - leap - 243;
}
else if(yday <= leap + 304)
{
gdate.month = 10;
gdate.day = yday - leap - 273;
}
else if(yday <= leap + 334)
{
gdate.month = 11;
gdate.day = yday - leap - 304;
}
else
{
gdate.month = 12;
gdate.day = yday - leap - 334;
}
return(gdate);
}
GDATE jeartogreg(double jear)
{
return(jdaytogreg((long)((jear - 1) * AVYRDAYS + .5)));
}
/*
**************************************************************************
These functions convert between string and gregorian
**************************************************************************
*/
GDATE mmddyyyytogreg(char *chrp, int nearyear)
{
GDATE gdate;
/*
mmddyyyytogreg() changes a null terminated string
to a gregorain GDATE format date.
*/
/* convert month */
gdate.month = atoi(chrp);
/* find and convert day */
while(isdigit(*chrp++)); /* skip to next non-digit plus one */
gdate.day = atoi(chrp);
/* find and convert year */
while(isdigit(*chrp++)); /* skip to next non-digit plus one */
gdate.year = yytoyear(chrp, nearyear);
return(gdate);
}
int yytoyear(char *str, int nearyear)
{
char *digitp;
int year;
digitp = str;
while(isdigit(*digitp++)); /* skip to next non-digit plus one */
if(nearyear > 0 && digitp - str <= 3){
year = atoi(str) + (nearyear - MAXYY) / 100 * 100;
if(abs(nearyear - year) >= MAXYY)
year += 100;
}
else
year = atoi(str);
return(year);
}
char *gregtommddyyyy(char *str, GDATE gdate, int nearyear)
{
int diff;
diff = abs(gdate.year - nearyear);
if(nearyear <= 0 || diff > MAXYY)
/* output 4 digits */
sprintf
(
str, "%02d/%02d/%04d", gdate.month, gdate.day, gdate.year
);
else
/* output 2 digits */
sprintf
(
str, "%02d/%02d/%02d", gdate.month, gdate.day, gdate.year % 100
);
return str;
}
/*
**************************************************************************
These are additional date related functions
**************************************************************************
*/
int isleap(int year)
{
if(year %